package com.ayz.gateway.core.core;

import com.alibaba.fastjson.JSON;

import com.ayz.gateway.core.core.Exception.ContentTypeNotSupportException;
import com.ayz.gateway.core.core.Exception.HttpRequestParserException;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName HttpRequestParser
 * @Description TODO: 对于网关网络请求进行参数解析
 *
 * @Author 快乐的星球
 * @Date 2023/5/9 23:10
 * @Version 1.0
 **/
public class HttpRequestParser {
    /**
     * 解析请求
     * @param httpRequest
     * @return 返回一个Map结构 key:参数名称 value:参数的值
     */
    public static Map<String, Object> parseRequest(FullHttpRequest httpRequest){
        HttpMethod method = httpRequest.method();
        HashMap<String, Object> parameters=new HashMap<>();
        if(method==HttpMethod.GET){
            //GET 请求参数默认放在uri路径中 通过 ?name1=value1&name2=value2 的方式传入参数
            //使用Netty的组件进行参数的解析
            QueryStringDecoder decoder=new QueryStringDecoder(httpRequest.uri());
            decoder.parameters().forEach((name,value)->{
                parameters.put(name,value.get(0));
            });
            return parameters;
        }else if(method==HttpMethod.POST){
            //最常用的就是 POST配合 JSON格式使用
            //获取在响应体里面的类型
            String contentType = httpRequest.headers().get(HttpHeaderNames.CONTENT_TYPE);
            switch (contentType){
                case "application/json":
                    //POST请求配合响应体里面放入JSON数据
                    ByteBuf byteBuf = httpRequest.content().copy();
                    if(byteBuf.isReadable()){
                        CharSequence charSequence = byteBuf.readCharSequence(byteBuf.readableBytes(), StandardCharsets.UTF_8);
                        String jsonStr = charSequence.toString();
                        return JSON.parseObject(jsonStr);
                    }
                    break;
                case "multipart/form-data":
                    //通过表单将数据使用请求体中传输
                    HttpPostRequestDecoder decoder=new HttpPostRequestDecoder(httpRequest);
                    decoder.offer(httpRequest);
                    decoder.getBodyHttpDatas().forEach((data)->{
                        //响应体中的属性
                        Attribute attr=(Attribute) data;
                        try {
                            parameters.put(attr.getName(),attr.getValue());
                        }catch (IOException exception){
                        }
                    });
                    return parameters;
                default:
                    throw new ContentTypeNotSupportException(contentType);
            }
        }
        throw new HttpRequestParserException();
    }
}
